接續著前一天沒做完的新增功能,今天繼續接著做~邊做也一邊介紹用到的方法與程式碼。
我們再次回到storyboard,從畫面右上角的選項進入連結controller的地方,然後選擇相對應的classentryViewController
。
在這個畫面中,我們希望可以顯示欲新增的to-do的內容與時間,因此需要新增一些UI元件。
除此之外,為了方便起見,我們可以在同一個畫面指定一個storyboard Id,在這邊我們打上enter
,到時候可以在程式面去連結。
storyboard id不能重複
接著找到TextField,用來顯示todo的標題,或稱作內容。找到後也是一樣,直接拖移到剛剛選擇的畫面當中。
然後設定constraints,包含margin(上左右分別為0)、以及height(20...50,隨便XD)
剛剛還提到了要有一個日期,因此我們點右上角新增,然後搜尋UIDatePicker,拖拉至畫面中。同樣的,設定constraints,在這邊我設定上50、下左右為0。可得到下圖的畫面。
昨天提到outlet是程式中有宣告的元件,因此我們將UIDatePicker加上程式的對應變數,如下。
好了,畫面元件的部分應該就到此為止。我們來把還沒寫完的程式部分補齊。
主畫面上面,已經新增了右上角的加號 :heavy_plus_sign: ,不過按下按鈕後做什麼行為我們還沒定義。
還記得幾天前我們解析過新的寫法guard let
其實可以就理解成if let
。
因此這邊使用方法instantiateViewController
,利用我們剛剛指定的identifier="enter"去建立出一個新的storyboard相對應的controller。
@IBAction func didTapAddButton() {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "enter") as? EntryViewController else {
return
}
vc.title = "New Item"
vc.navigationItem.largeTitleDisplayMode = .never
navigationController?.pushViewController(vc, animated: true)
}
navigationController
就像是一個容器,裡面可以用來放置及疊放各個頁面,畫面上方預設會有一個導覽列( Navigation Bar ) ,其中可以放置標題及按鈕,來切換或退出頁面,像是內建的 設定 App 就是一個例子。
因此,方法pushViewController
就是把新的頁面push到當下的stack中。
當我們新增完一個新項目之後,我們希望畫面可以重撈資料、並將所有的東西放到tableView裡,當然,包含新項目。
首先,在這個畫面,我們先嘗試與資料庫連線。
private let realm = try! Realm()
接著,在didTapAddButton
新增一個handler,然後就是讓我頭痛了好久的...
vc.completionHandler = { [weak self] in
self?.refresh()
}
weakIn Swift, we need to use weak self and unowned self to give ARC *(Automatic Reference Counting,協助我們管理memory以及reference)* the required information between relationships in our code. Without using weak or unowned you’re basically telling ARC that a certain “strong reference” is needed and you’re preventing the reference count from going to zero. **Without correctly using these keywords we possibly retain memory which can cause memory leaks in your app.** So-called Strong Reference Cycles or Retain Cycles can occur as well if weak and unowned are not used correctly.^2^
雖說大致理解weak的用途與目的,不過何時使用、如何使用,看越多資料,就會發現有越多無法理解的專有名詞 (´−`) ンー崩潰
誠摯希望有善心人士可以協助解釋,或是分享你曾看過好懂的解說文
當畫面load進memory時,我們將資料庫的資料mapping到我們宣告的物件
data = realm.objects(TodoListItem.self).map({$0})
因應剛剛提到的reload資料,我們新增一個refresh
如下
func refresh() {
data = realm.objects(TodoListItem.self).map({$0})
table.reloadData()
}
然後就可以跑了!
接下來做新增的按鈕,笑死打完發現不能新增 (~ ̄▽ ̄)~